package com.jrauto.CarAppBackend.controller;

import com.jrauto.CarAppBackend.entity.dto.LoginRequest;
import com.jrauto.CarAppBackend.entity.dto.RegisterRequest;
import com.jrauto.CarAppBackend.entity.vo.AuthResponse;
import com.jrauto.CarAppBackend.entity.User;
import com.jrauto.CarAppBackend.entity.dto.BindPhoneDTO;
import com.jrauto.CarAppBackend.entity.vo.LoginVO;
import com.jrauto.CarAppBackend.service.FileStorageService;
import com.jrauto.CarAppBackend.service.UserService;
import com.jrauto.CarAppBackend.utils.R;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.annotation.Resource;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * @author : huiMing
 * Date : 2025年06月23日 10:33
 * @version V1.0
 */
@RestController
@RequestMapping("/auth")
public class UserController {

    @Resource
    private UserService userService; // 注入用户业务服务

    @Resource
    private FileStorageService fileStorageService;

    /**
     * 用户注册接口
     *
     * @param request 注册请求 DTO
     * @return 注册结果响应
     */
    @PostMapping("/register")
    // @Validated 启用 JSR303 校验，对 RegisterRequest 进行参数校验
    public ResponseEntity<AuthResponse> register(@Validated @RequestBody RegisterRequest request) {
        System.out.println(request);
        try {
            User registeredUser = userService.registerUser(request);
            // 构建只包含用户ID和手机号的 Map，作为 AuthResponse 的数据部分
            Map<String, Object> userData = new HashMap<>();
            userData.put("id", registeredUser.getId());
            userData.put("phone", registeredUser.getPhone());
            userData.put("gender", registeredUser.getGender());
            // 注册成功，返回 200 OK 和成功消息
            return ResponseEntity.ok(new AuthResponse(
                    HttpStatus.OK.value(),
                    "注册成功",
                    // 返回部分用户数据，如 ID 和手机号，不包含敏感信息
                    userData // 直接返回 Map

            ));
        } catch (RuntimeException e) {
            // 捕获业务异常，返回 400 Bad Request 和错误消息
            return ResponseEntity.badRequest().body(new AuthResponse(
                    HttpStatus.BAD_REQUEST.value(),
                    e.getMessage(),
                    null
            ));
        } catch (Exception e) {
            // 捕获其他未知异常，返回 500 Internal Server Error
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new AuthResponse(
                    HttpStatus.INTERNAL_SERVER_ERROR.value(),
                    "服务器内部错误",
                    null
            ));
        }
    }

    /**
     * 用户登录接口
     *
     * @param request 登录请求 DTO
     * @return 登录结果响应 (包含 JWT Token 和用户基本信息)
     */
    @Operation(summary = "用户登录接口")
    @PostMapping("/login")
    public ResponseEntity<AuthResponse> login(@Validated @RequestBody LoginRequest request) {
        try {
            String token = userService.login(request); // 调用登录服务获取 JWT Token
            // 登录成功后，从数据库获取用户基本信息用于返回
            User user = userService.findUserByPhone(request.getPhone());
            if (user == null) {
                // 理论上这里不会发生，因为登录服务已经验证了用户存在
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(new AuthResponse(
                        HttpStatus.UNAUTHORIZED.value(),
                        "登录失败：用户不存在",
                        null
                ));
            }

            // 构建登录成功响应数据 (不包含密码和敏感状态信息)
            Map<String, Object> loginData = new HashMap<>();
            loginData.put("token", token);
            loginData.put("user", new HashMap<String, Object>() {{
                put("id", user.getId());
                put("phone", user.getPhone());
                put("nickname", user.getNickname());
                put("role", user.getRole());
                put("gender", user.getGender());
                put("avatar", user.getAvatar());
                put("status", user.getStatus());
                put("openid", user.getOpenid());
                put("email", user.getEmail());
                // 不返回 password 和 status 等敏感信息
            }});

            return ResponseEntity.ok(new AuthResponse(
                    HttpStatus.OK.value(),
                    "登录成功",
                    loginData
            ));
        } catch (RuntimeException e) {
            // 捕获业务异常 (如手机号或密码不正确，用户被锁定/删除)
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(new AuthResponse(
                    HttpStatus.UNAUTHORIZED.value(),
                    e.getMessage(),
                    null
            ));
        } catch (Exception e) {
            // 捕获其他未知异常
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new AuthResponse(
                    HttpStatus.INTERNAL_SERVER_ERROR.value(),
                    "服务器内部错误",
                    null
            ));
        }
    }


    /**
     * 处理微信登录请求
     * @param code 微信登录请求code
     * @return 包含JWT Token和用户信息的响应
     */
//    @PostMapping("/wxLogin")
//    public R<LoginVO> wechatLogin(@RequestBody String code) {
//        try {
//            LoginVO response = userService.wechatLogin(code);
//            return R.ok("登录成功", response);
//        } catch (RuntimeException e) {
//            // 微信登录失败，返回错误信息
//            return R.fail(e.getMessage());
//        }
//    }


    /**
     * 用户登录 微信小程序
     *
     * @param code
     * @return
     */
//    @GetMapping("/login")
//    public ResponseEntity<User> login(String code) {
//        // 调用微信小程序登录接口获取 openid
//        String openid = userService.getOpenid(code);
//        User user = userService.login(openid);
//        return ResponseEntity.ok(user);
////        return Result.success(200, "登录成功", user);
//    }
    @GetMapping("/get-openid")
    public String getOpenid(@RequestParam("code") String code) {
        return userService.getOpenid(code);
    }


    /**
     * 生成6为验证码
     *
     * @param phoneNumber
     * @return
     */

    @PostMapping("/generate-code")
    public String generateVerificationCode(@RequestParam("phoneNumber") String phoneNumber) {
        if (phoneNumber == null || phoneNumber.trim().isEmpty()) {
            return "Error: Phone number cannot be empty.";
        }
        String verificationCode = generateRandomSixDigitCode();
        System.out.println("Generated code " + verificationCode + " for phone number: " + phoneNumber);
        return verificationCode;
    }

    /**
     * @return A string representing a 6-digit random number.
     */
    private String generateRandomSixDigitCode() {
        Random random = new Random();
        // Generate a number between 100000 (inclusive) and 999999 (inclusive)
        int code = 100000 + random.nextInt(900000);
        return String.valueOf(code);
    }


    /**
     * 微信小程序通过手机号授权登录或注册
     *
     * @return 登录成功后的用户信息和 JWT Token
     */
    @PostMapping("/wxLogin")
    public R<LoginVO> wechatLoginByPhone(@RequestParam String code1, @RequestParam String code2) {
        System.out.println("code1: " + code1 + " code2: " + code2);
        // 1. 从请求体中获取 code
        if (code1 == null || code1.isEmpty() || code2 == null || code2.isEmpty()) {
            // 返回 400 Bad Request
            return null;
        }
        try {
            // 2. 调用 UserService 的业务逻辑
            LoginVO loginVO = userService.wechatLoginPhone(code1, code2);
            return R.ok("登录成功", loginVO); // 登录成功，返回 200 OK
        } catch (RuntimeException e) {
            // 3. 捕获业务异常，并返回相应的错误信息
            // 这里的异常信息可以根据具体情况更详细地返回
            System.err.println("登录失败：" + e.getMessage());
            return null;
        }
    }


    /**
     * 获取当前认证用户的ID
     *
     * @return 用户ID
     * @throws RuntimeException 如果用户未认证或无法获取用户ID
     */
    private Integer getCurrentUserId() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !authentication.isAuthenticated() || authentication.getPrincipal() instanceof String) {
            throw new RuntimeException("用户未认证或认证信息无效");
        }
        Object principal = authentication.getPrincipal();
        if (principal instanceof UserDetails) {
            String identifier = ((UserDetails) principal).getUsername(); // 获取 CustomUserDetailsService 返回的用户名 (手机号或openid)

            // ⭐️ 关键修改：使用新的 findUserByIdentifier 方法来查找用户 ⭐️
            User user = userService.findUserByIdentifier(identifier);

            if (user != null) {
                return user.getId();
            }
        }
        throw new RuntimeException("无法获取当前用户ID");
    }


    /**
     * 修改当前认证用户的密码
     *
     * @param password 包含旧密码和新密码的请求DTO
     * @return 响应实体
     */
    @PutMapping("/password")
    public ResponseEntity<String> changePassword(@RequestBody String password) {
        try {
            Integer userId = getCurrentUserId();
            System.out.println("userId: " + userId + " password: " + password);
            userService.changePassword(userId, password);
            return ResponseEntity.ok("密码修改成功");
        } catch (RuntimeException e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
        }
    }

    /**
     * 绑定手机号
     *
     * @param request 包含要绑定手机号的请求DTO
     * @return 响应实体
     */
    @PutMapping("/bindPhone")
    public ResponseEntity<String> bindPhone(@RequestBody BindPhoneDTO request) {
        try {
            Integer userId = getCurrentUserId();
            userService.bindPhone(userId, request);
            return ResponseEntity.ok("手机号绑定成功");
        } catch (RuntimeException e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
        }
    }

    /**
     * 解绑手机号
     *
     * @return 响应实体
     */
    @PutMapping("/unbindPhone")
    public ResponseEntity<String> unbindPhone() {
        try {
            Integer userId = getCurrentUserId();
            userService.unbindPhone(userId);
            return ResponseEntity.ok("手机号解绑成功");
        } catch (RuntimeException e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
        }
    }

    /**
     * 绑定微信OpenID
     *
     * @param code 微信code的请求
     * @return 响应实体
     */
    @PutMapping("/bindWechat")
    public ResponseEntity<String> bindWechat(@RequestBody String code) {
        try {
            Integer userId = getCurrentUserId();
            userService.bindWechat(userId, code);
            return ResponseEntity.ok("微信绑定成功");
        } catch (RuntimeException e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
        }
    }

    /**
     * 修改当前认证用户的昵称
     *
     * @param nickname 包含新昵称的请求DTO
     * @return 响应实体
     */
    @PutMapping("/nickname")
    public ResponseEntity<String> changeNickname(@RequestBody String nickname) {
        try {
            Integer userId = getCurrentUserId();
            userService.changeNickname(userId, nickname);
            return ResponseEntity.ok("修改成功");
        } catch (RuntimeException e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
        }
    }


    /**
     * 更新用户头像接口
     * POST /api/upload/avatar/{userId}
     *
     * @param userId 要更新头像的用户ID
     * @param file   头像图片文件
     * @return 包含新头像URL的响应
     */
    @PostMapping("/avatar/{userId}")
    public ResponseEntity<Map<String, String>> updateAvatar(@PathVariable Integer userId, @RequestParam("file") MultipartFile file) {
        try {
            // 1. 上传文件，获取文件名
            String fileName = fileStorageService.storeFile(file);
            // 2. 根据文件名拼接完整的访问URL
//            String avatarUrl = fileStorageService.getFileUrl(fileName);
            // 3. 更新用户头像信息到数据库
            userService.updateUserAvatar(userId, fileName);
            // 4. 返回成功响应
            Map<String, String> response = new HashMap<>();
            response.put("url", fileName);
            return ResponseEntity.ok(response);
        } catch (RuntimeException | IOException ex) {
            Map<String, String> errorResponse = new HashMap<>();
            errorResponse.put("error", "Failed to update user avatar: " + ex.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
        }
    }


}

